package com.zangchat.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.core.domain.AjaxResult;
import com.common.utils.StringUtils;
import com.common.utils.security.Md5Utils;
import com.zangchat.config.DataConfig;
import com.zangchat.domain.ChatAccount;
import com.zangchat.domain.ChatUsersLabel;
import com.zangchat.service.*;
import com.zangchat.utils.NetUtil;
import com.zangchat.utils.RedisUtil;
import com.zangchat.utils.Tools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zangchat.mapper.ChatUsersMapper;
import com.zangchat.domain.ChatUsers;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户 服务层实现
 *
 * @author wudi
 * @date 2020-07-06
 */
@Service
public class ChatUsersServiceImpl extends ServiceImpl<ChatUsersMapper, ChatUsers> implements IChatUsersService
{
    @Autowired
    private ISmsService smsService;
    @Autowired
    private IChatAccountService chatAccountService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IChatUsersLabelService chatUsersLabelService;
    @Autowired
    private NearBySearchService nearBySearchService;
    /**
     *
     * 用户同意授权，获取code
     */
    @Override
    public AjaxResult getUrlForoauth(HttpServletRequest request) {
        String appid = DataConfig.APPID;
        String redirectUri = DataConfig.REDIRECT_URI;
        String responseType = DataConfig.responseType;
        String scope = DataConfig.scope;
        String state = DataConfig.state;
        String uri = NetUtil.urlEncodeUTF8(redirectUri);
        String replace_rui ="http%3a%2f%2f"+ uri.replace("%2Fapi%2Fwx%2F", "%2fapi%2fwx%2f");
        String urlNameString = DataConfig.PUBLIC_NUMBER_URL+ appid+"&redirect_uri="+replace_rui+"&response_type="+responseType+"&scope="+scope+"&state="+state+"#wechat_redirect";
        return AjaxResult.success(urlNameString);
    }



    /**
     * 公众号关注
     * @param jsonObject
     * @param request
     * @return
     */
    @Override
    public AjaxResult vxOauthLogin(JSONObject jsonObject, HttpServletRequest request) {
        String openid = jsonObject.getString("openid");
//        String nickname = jsonObject.getString("nickname");
//        String sex = jsonObject.getString("sex");
//        String city = jsonObject.getString("city");
//        String province = jsonObject.getString("province");
//        String country = jsonObject.getString("country");
//        String headimgurl = jsonObject.getString("headimgurl");
        ChatUsers chatUsers=new ChatUsers();
        chatUsers.setVxOpenid(openid);
        QueryWrapper<ChatUsers> queryWrapper=new QueryWrapper<>(chatUsers);
        ChatUsers chatUsers1 = baseMapper.selectOne(queryWrapper);
        if (chatUsers1==null){
            baseMapper.insert(chatUsers);
        }

//        String[] key=new String[]{"userData",openid};
//        String redisUtilKey = redisUtil.createKey(key);
//        redisUtil.set(redisUtilKey,jsonObject,60*60*24*30L);
        return AjaxResult.success(jsonObject);
    }


    /**
     *  关注公主号后注册
     * @param vxOpenid 微信openid
     * @param userPhone 手机号
     * @param password 密码
     * @param confirmPassword 确认密码
     * @param smsCode 手机验证码
     * @param request
     * @return
     */
    @Override
    @Transactional
    public AjaxResult registerAfterVxOauthLogin(String vxOpenid, String userPhone,String password, String confirmPassword,String smsCode, HttpServletRequest request) {

        if(StringUtils.isEmpty(vxOpenid)){
            return AjaxResult.error("用户openid不能为空");
        }
        if(StringUtils.isEmpty(userPhone)){
            return AjaxResult.error("用户手机不能为空");
        }
        if(StringUtils.isEmpty(confirmPassword)){
            return AjaxResult.error("确认密码不能为空");
        }
        if(StringUtils.isEmpty(smsCode)){
            return AjaxResult.error("短信验证码不能为空");
        }
        if (password.length() < 6){
            return AjaxResult.error("密码长度最少6位");
        }

        if (password.length() > 16) {
            return AjaxResult.error("密码长度最多16位");
        }
        if(!password.equals(confirmPassword)){
            return AjaxResult.error("密码与确认密码不一致");
        }
        if (Tools.passwordRegex(password)){
            return AjaxResult.error("密码包含数字和英文字母");
        }
        AjaxResult ajaxResult = smsService.checkCode(userPhone, smsCode, "1");
        if (!"200".equals(ajaxResult.get("code").toString())) {
            return AjaxResult.error("短信验证码错误");
        }
        ChatUsers checkuserPhoneChatUsers=new ChatUsers();
        checkuserPhoneChatUsers.setUserPhone(userPhone);
        QueryWrapper<ChatUsers> queryWrapper=new QueryWrapper<>(checkuserPhoneChatUsers);
        ChatUsers chatUsers = baseMapper.selectOne(queryWrapper);
        if (chatUsers!=null){
            return AjaxResult.error("新增用户'" + userPhone + "'失败，手机号码已存在");
        }

        String userName= Md5Utils.hash(vxOpenid);
        try{
            ChatUsers paramQlwShopUsers=new ChatUsers();
            paramQlwShopUsers.setVxOpenid(vxOpenid);

            int salt = Tools.getSalt();
            String newPassWord=password.concat(salt+"");
            paramQlwShopUsers.setPassword(Md5Utils.hash(newPassWord));
            paramQlwShopUsers.setUserName(userName);
            paramQlwShopUsers.setUserPhone(userPhone);
            paramQlwShopUsers.setSalt(salt);
            int i = baseMapper.insert(chatUsers);
            if (i<1){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("新增用户失败");
            }
            //插入账户表
            return AjaxResult.success();
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("新增用户失败");
        }
    }

    @Override
    @Transactional
    public AjaxResult register(String userPhone, String password, String confirmPassword, String smsCode, String invite) {
        ChatUsers registerUsers=new ChatUsers();
        if(StringUtils.isEmpty(userPhone)){
            return AjaxResult.error("手机号不能为空");
        }
        if(StringUtils.isEmpty(password)){
            return AjaxResult.error("密码不能为空");
        }
        if(StringUtils.isEmpty(confirmPassword)){
            return AjaxResult.error("确认密码不能为空");
        }
        if(!password.equals(confirmPassword)){
            return AjaxResult.error("密码与确认密码不一致");
        }
        if(StringUtils.isEmpty(smsCode)){
            return AjaxResult.error("短信验证码不能为空");
        }
        if (password.length() < 6){
            return AjaxResult.error("密码长度最少6位");
        }
        if (password.length() > 16) {
            return AjaxResult.error("密码长度最多16位");
        }
        if(!password.equals(confirmPassword)){
            return AjaxResult.error("密码与确认密码不一致");
        }
        if (!Tools.passwordRegex(password)){
            return AjaxResult.error("密码包含数字和英文字母");
        }
        AjaxResult ajaxResult = smsService.checkCode(userPhone, smsCode, "1");
        if (!"1".equals(ajaxResult.get("code").toString())) {
            return AjaxResult.error("短信验证码错误");
        }
        ChatUsers chatUsers = this.checkedUserPhone(userPhone);
        if (chatUsers!=null){
            return AjaxResult.error("新增用户'" + userPhone + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(invite)){
            ChatUsers chatUsers1 = this.checkedUserPhone(invite);
            if (chatUsers1==null){
                return AjaxResult.error("推荐人"+invite+"不存在");
            }

            registerUsers.setInviteId(chatUsers1.getId());
        }
        String key = Md5Utils.hash("zangchat" + userPhone + "addUser");
        try{

            int salt =Tools.getSalt();
            String newPassWord=password.concat(salt+"");
            registerUsers.setPassword(Md5Utils.hash(newPassWord));
            registerUsers.setUserPhone(userPhone);
            registerUsers.setUserName(userPhone);
            registerUsers.setSalt(salt);
            registerUsers.setCreateTime(new Date());
            int i = baseMapper.insert(registerUsers);
            if (i<1){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("新增用户失败");
            }
            //用户账户
            ChatAccount chatAccount=new ChatAccount();
            chatAccount.setUserId(registerUsers.getId());
            chatAccount.setCreateTime(new Date());
            int j = chatAccountService.getBaseMapper().insert(chatAccount);
            if (j<1){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("新增用户账户失败");
            }

            redisUtil.remove(key);
            return AjaxResult.success("注册成功");
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            if (redisUtil.isKeyInCache(key)) {
                redisUtil.update(key, smsCode+"", 3000L);
            } else {
                redisUtil.set(key, smsCode+"", 3000L);
            }
            return AjaxResult.error("新增用户失败");
        }
    }

    @Override
    public ChatUsers checkedUserPhone(String userPhone) {
        ChatUsers checkuserPhoneUsers=new ChatUsers();
        checkuserPhoneUsers.setUserPhone(userPhone);
        QueryWrapper<ChatUsers> queryWrapper=new QueryWrapper(checkuserPhoneUsers);
        return baseMapper.selectOne(queryWrapper);

//        if (chatUsers!=null){
//            return AjaxResult.success(1);
//        }else {
//            return AjaxResult.success(0);
//        }
    }

    @Override
    public AjaxResult login(String userPhone, String password,String derviceId ,double longitude,double latitude) {
        if(StringUtils.isEmpty(userPhone)){
            return AjaxResult.error("手机号不能为空");
        }
        if(StringUtils.isEmpty(password)){
            return AjaxResult.error("密码不能为空");
        }
        ChatUsers chatUsers = this.checkedUserPhone(userPhone);
        if (chatUsers==null){
            return AjaxResult.error("输入的手机号错误");
        }
        Integer salt = chatUsers.getSalt();
        String checkPassword = Md5Utils.hash(password.concat(salt + ""));
        if (!chatUsers.getPassword().equals(checkPassword)){
            return AjaxResult.error("密码错误请重新输入");
        }
        Integer status = chatUsers.getStatus();
        if ("-1".equals(status)){
            return AjaxResult.error("你的账号已被冻结");
        }

        //储存设备号Id
        redisUtil.set(chatUsers.getId().toString(),derviceId);
        if (StringUtils.isNotNull(longitude)&& StringUtils.isNotNull(latitude)){
            nearBySearchService.save(chatUsers.getId(),longitude,latitude);
        }
        Map<String,Object> map=new HashMap<>();
        map.put("id",chatUsers.getId());
        map.put("sex",chatUsers.getSex());
        map.put("userName",chatUsers.getUserName());
        map.put("userPhone",chatUsers.getUserPhone());
        map.put("headImg",chatUsers.getHeadImg());
        //设备唯一标识存入缓存
        return AjaxResult.success(map);
    }

    /**
     * 校验用户
     * @param userId
     * @return
     */
    @Override
    public AjaxResult checkedUser(Long userId){
        if (StringUtils.isNull(userId)){
            return AjaxResult.error("获取用户信息失败，请重新登录");
        }
        ChatUsers chatUsers = baseMapper.selectById(userId);
        if (chatUsers==null){
            return AjaxResult.error("获取用户信息失败，请重新登录");
        }
        if (chatUsers.getStatus()!=1){
            return AjaxResult.error("该用户已被锁定");
        }

        return AjaxResult.success();
    }

    /**
     * 忘记密码
     * @param userPhone
     * @param smsCode
     * @param newPassword
     * @param confirmPassword
     * @param type
     * @return
     */
    @Override
    public AjaxResult forgetPassword(String userPhone,String smsCode, String newPassword, String confirmPassword,String type) {
        //校验手机号是否存在
        ChatUsers chatUsers = checkedUserPhone(userPhone);
        if (StringUtils.isNull(chatUsers)){
            return AjaxResult.error("手机号不存在");
        }
        //校验短信验证码是否正确
        AjaxResult ajaxResult = smsService.checkCode(userPhone, smsCode, type);
        if (ajaxResult.get("code").equals(-1)){
            return AjaxResult.error(ajaxResult.get("msg").toString());
        }
        //验证二次密码
        if(!newPassword.equals(confirmPassword)){
            return AjaxResult.error("二次密码输入错误");
        }

        ChatUsers checkuserPhoneChatUsers=new ChatUsers();
        checkuserPhoneChatUsers.setPassword(Md5Utils.hash(newPassword.concat(chatUsers.getSalt()+"")));
        QueryWrapper<ChatUsers> queryWrapper=new QueryWrapper<>(new ChatUsers()).eq("user_phone",userPhone).eq("status",1);
        int update = baseMapper.update(checkuserPhoneChatUsers, queryWrapper);
        if (update<1){
            return AjaxResult.error("密码修改错误");
        }
        return AjaxResult.success("密码修改成功");
    }

    /**
     * 修改密码
     * @param userPhone
     * @param oldPassword
     * @param newPassword
     * @param confirmPassword
     * @return
     */
    @Override
    public AjaxResult updatePassword(String userPhone, String oldPassword, String newPassword, String confirmPassword) {
        if (oldPassword.equals(newPassword)){
            return AjaxResult.error("旧密码不能与新密码相同");
        }
        //校验用户是否存在
        ChatUsers chatUsers = checkedUserPhone(userPhone);
        if (StringUtils.isNull(chatUsers)){
            return AjaxResult.error("手机号不存在");
        }
        //校验原密码是否正确
        String password = Md5Utils.hash(oldPassword.concat(chatUsers.getSalt() + ""));
        if (!chatUsers.getPassword().equals(password)){
            return AjaxResult.error("原密码输入错误");
        }
        //校验二次密码
        if (!newPassword.equals(confirmPassword)){
            return AjaxResult.error("二次密码输入错误");
        }
        ChatUsers checkuserPhoneChatUsers=new ChatUsers();
        checkuserPhoneChatUsers.setPassword(Md5Utils.hash(newPassword.concat(chatUsers.getSalt()+"")));
        QueryWrapper<ChatUsers> queryWrapper=new QueryWrapper<>(checkuserPhoneChatUsers).eq("user_phone",userPhone).eq("status",1);
        int update = baseMapper.update(checkuserPhoneChatUsers, queryWrapper);
        if (update<1){
            return AjaxResult.error("修改密码错误");
        }
        return AjaxResult.success("修改密码成功");
    }

    /**
     * 我的资料
     * @param userId
     * @return
     */
    @Override
    public AjaxResult getUserDetail(Long userId) {
        ChatUsers chatUsers = baseMapper.selectById(userId);
        return AjaxResult.success("获取成功",chatUsers);
    }

    public ChatUsers getUsersDataById(Long userId){
        return baseMapper.selectById(userId);
    }

    @Override
    public int supplementOne(Long userId, Integer sex, String userName, String headImg) {
        ChatUsers chatUsers=new ChatUsers();
        chatUsers.setId(userId);
        chatUsers.setSex(sex);
        chatUsers.setHeadImg(headImg);
        chatUsers.setUserName(userName);

        return baseMapper.updateById(chatUsers);
    }

    @Override
    @Transactional
    public AjaxResult supplementTwo(Long userId, String flagList, String cover) {
        ChatUsers chatUsers=new ChatUsers();
        chatUsers.setId(userId);
        if (StringUtils.isNotBlank(flagList)){
            String[] flages = flagList.split(",");
            for (String flag : flages) {
                ChatUsersLabel chatUsersLabel=new ChatUsersLabel();
                chatUsersLabel.setLabelId(Long.parseLong(flag));
                chatUsersLabel.setUserId(userId);
                int k = chatUsersLabelService.getBaseMapper().insert(chatUsersLabel);
                if (k<1){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error();
                }
            }

        }
        //判断是否为本人
        Integer isCover = chatUsers.getIsCover();
        if (isCover==-1){
            if ("是本人".equals("是本人")){
                chatUsers.setIsCover(1);
                //发放奖励
                //生成流水
            }
        }
        chatUsers.setCover(cover);
        int i = baseMapper.updateById(chatUsers);
        if (i<1){
           TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
           return AjaxResult.error();
        }
        return AjaxResult.success();
    }

}